/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ufba.lasid.virtualization;

import br.ufba.lasid.ds.GroupView;
import br.ufba.lasid.ds.api.IGroupView;
import br.ufba.lasid.ds.api.IReplicaHandler;
import br.ufba.lasid.utils.Base;
import br.ufba.lasid.virtualization.api.IReplicatedVirtualMachineHandler;
import java.io.BufferedReader;
import java.net.Inet4Address;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author aliriosa
 */
public class ReplicatedXenVMHandler extends XenVMHandler implements Runnable, IReplicatedVirtualMachineHandler {

    String location = null;
    GroupView group = new GroupView();
    String drbdResource = null;
    String localRole = null;
    String remoteRole = null;

    public void start() {
        new Thread(this).start();
    }

    @Override
    public void run() {
        while (true) {
            if (localRole != null && remoteRole != null) {
                for (IReplicaHandler replica : group) {
                    if (replica != this) {
                        try {
//                            EState state = failureDetector.queryStatus(replica.getLocation());
//                            if(state.equals(EState.CRASHED)){
//                                System.out.println("[DEBUG] Replica " + replica + " is crashed!");
//                            }
                        } catch (Exception ex) {
                            Logger.getLogger(ReplicatedXenVMHandler.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                }
            }
        }

    }

    public ReplicatedXenVMHandler() throws Exception {
        this.location = Inet4Address.getLocalHost().getHostAddress();
        this.group.add(this);
    }

    @Override
    public String getLocation() throws Exception {
        return location;
    }

    @Override
    public void setLocation(String location) throws Exception {
        this.location = location;
    }

    @Override
    public String toString() {
        return getId() + "@" + location;
    }

    @Override
    public IGroupView getGroupView() {
        return group;
    }

    protected void updateRole() throws Exception {

        if (hasDRBDResource()) {
            System.out.println("[DEBUG]drbdadm role " + drbdResource);

            Process p = Runtime.getRuntime().exec("drbdadm role " + drbdResource);

            BufferedReader reader = Base.getProcessInput(p);

            String outString = reader.readLine();

            System.out.println(outString);


            if (outString != null) {

                outString = outString.toLowerCase();

                int i = outString.indexOf("/");

                localRole = outString.substring(0, i);
                remoteRole = outString.substring(i);
            }
        }
    }

    @Override
    public boolean isPrimary() throws Exception {
        System.out.println(localRole);
        if (localRole != null) {
            return localRole.equals("primary");
        }
        return false;
    }

    @Override
    public boolean hasDRBDResource() throws Exception {
        return drbdResource != null;
    }

    @Override
    public String getDRBDResource() throws Exception {
        return drbdResource;
    }

    @Override
    public void connect(String vmid) throws Exception {
        super.connect(vmid);
        System.out.println("[DEBUG]grep drbd " + getConfigFile());
        Process p = Runtime.getRuntime().exec("grep drbd " + getConfigFile());

        BufferedReader reader = Base.getProcessInput(p);

        String disk = reader.readLine();

        if (disk != null) {
            int i0 = disk.indexOf(":");
            int i1 = disk.indexOf(",", i0);

            drbdResource = disk.substring(i0 + 1, i1);

            if (drbdResource != null) {
                drbdResource = drbdResource.trim();
            }
        }
    }

    @Override
    public void sync() throws Exception {
        this.updateRole();
        if (localRole != null && remoteRole != null) {
            if (localRole.equals(remoteRole)) {
                System.out.println(localRole + " " + remoteRole);
                return;
            }

            if (isPrimary()) {
                //            this.checkpoint();
                System.out.println("checkpoint " + this.getId());
            } else {
                //            this.restore();
                System.out.println("restoure " + this.getId());
            }
        }
    }
}
